package com.bjsxt.userscenter.springmvc.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.bjsxt.userscenter.common.controller.BaseController;
import com.bjsxt.userscenter.common.util.ConstatFinalUtil;
import com.bjsxt.userscenter.common.util.PageInfoUtil;
import com.bjsxt.userscenter.users.pojo.AAdmins;
import com.bjsxt.userscenter.users.pojo.AAdminsEnum;
import com.bjsxt.userscenter.users.service.IUsersService;

/**
 * 不需要登陆就可以访问的Controller
 * 
 * @author WangshSxt
 */
@Controller
public class NoLoginController extends BaseController
{
	/**
	 * Service如何赋值 通过Dubbo赋值, Dubbo的消费者
	 */
	@Resource
	private IUsersService usersService;

	/**
	 * 第一个例子
	 * 
	 * @return
	 */
	@RequestMapping("/hw")
	public String hw()
	{
		System.out.println("===第一个例子===");
		return "/head/hw";
	}

	/**
	 * Controller的方法和requestMapp和jsp的文件名三个一致 字符串转换成日期的对象,放到Controller的方法中实现,
	 * 如果要用Spring自动赋值,自动转换;需要提供一个转换器
	 * 
	 * @return
	 */
	@RequestMapping("/adminsList")
	public String adminsList(HttpServletRequest request, String currentPage, String pageSize, String keyword,
			String status, String st, String ed, Model model)
	{
		ConstatFinalUtil.SYS_LOGGER.info("==adminsList==");

		if ("get".equalsIgnoreCase(request.getMethod()))
		{
			/* 处理get方式的乱码 */
			/* tomcat是ISO8859-1的编码,因为它只占用一个字节 */
			try
			{
				ConstatFinalUtil.SYS_LOGGER.info("--转码前-:{}", keyword);
				/*
				 * ~将乱码的字符串使用指定的编码打散成字节数组 ~拿到打散的字节数组使用指定的编码组装 ~乱码的产生:
				 * 存储的时候编码与读取的编码不一样,就是乱码(人看的是乱码),机器认为的不是乱码
				 */
				keyword = new String(keyword.getBytes("ISO8859-1"), "UTF-8");
				ConstatFinalUtil.SYS_LOGGER.info("--转码后-:{}", keyword);
			} catch (Exception e)
			{
			}
		}

		/*
		 * 将字符串变成时间
		 */
		if (st == null)
		{
			st = "";
		}
		if (ed == null)
		{
			ed = "";
		}
		if (status == null)
		{
			status = "";
		}

		/* 搜索条件 */
		Map<String, Object> condMap = new HashMap<String, Object>();
		condMap.put("keyword", keyword);
		if (!"".equalsIgnoreCase(status))
		{
			condMap.put("status", status);
		}

		Date stDate = null;
		Date edDate = null;
		if (!"".equalsIgnoreCase(st) && !"".equalsIgnoreCase(ed))
		{
			/*
			 * 将字符串转换成日期
			 * 
			 * 完善了DateFormatUtil
			 */
			stDate = this.dateFormatUtil.strDateTime(st);
			edDate = this.dateFormatUtil.strDateTime(ed);
			;
		}
		condMap.put("stDate", stDate);
		condMap.put("edDate", edDate);

		PageInfoUtil pageInfoUtil = proccedPageInfo(currentPage, pageSize);

		/* 查询结果 */
		Map<String, Object> adminsList = this.usersService.findCondListAdminsService(pageInfoUtil, condMap);
		/* 将结果放到四大作用域中 */
		model.addAttribute("adminsList", adminsList);
		model.addAttribute("pageInfoUtil", pageInfoUtil);

		/* 将查询条件放到request中 */
		model.addAttribute("keyword", keyword);
		model.addAttribute("status", status);
		model.addAttribute("st", st);
		model.addAttribute("ed", ed);
		return "/back/adminsList";
	}

	/*
	 * 打开登陆页面
	 */
	@RequestMapping("/login")
	public String login()
	{
		ConstatFinalUtil.SYS_LOGGER.info("开始登陆");
		return "back/login";
	}

	/*
	 * 登录提交操作 按照邮箱查询管理员 查询出来的管理员邮箱比对密码 比对状态，放到session中， 更新上次登陆时间，页面跳转
	 * 利用邮箱和密码进行登录
	 */
	@RequestMapping("/loginSubmit")
	public String loginSubmit(HttpSession session,Model model, String email, String password,String code)
	{
		ConstatFinalUtil.SYS_LOGGER.info("===loginSubmit===");
		/*
		 * 在BaseController中session.setAttribute("rand", verifyCode);  
		 * 因为验证码放在了session中，所以要利用session去判断
		 * 获取验证码,开始测试验证码
		 */
		String randSess=session.getAttribute("rand")+"";
		/*
		 * 当验证码与图片中的验证码或者与万能验证码相同时，可以去验证邮箱
		 * "0175".equalsIgnoreCase(code)相当于设置了一个万能的验证码，一定要注意中间是||
		 */
		if(randSess.equalsIgnoreCase(code) || "0175".equalsIgnoreCase(code))
		{
			// 检验邮箱
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("email", email);
			AAdmins admins = this.usersService.findOneAdminsService(map);
			if (admins != null)
			{
				ConstatFinalUtil.SYS_LOGGER.info("上次登录的时间{}",admins.getFaildTime());
				/*
				 * 对于新用户，首先要判断一下admins.getFaildTime()是否为空
				 *密码不验证 
				 *当次数大于最大次数,&& 时间在十分钟以内
				 *写这个的方法是
				 */
				
				if(admins.getFaildTime() != null)
				{
					if(new Date().getTime()-admins.getFaildTime().getTime()<Long.valueOf(ConstatFinalUtil.CONFIG_JSON.get("password.error.lockTime")+"")
							&& admins.getFaildCount()<Integer.valueOf(ConstatFinalUtil.CONFIG_JSON.get("password.error.maxCount")+""))
					{
						info = "密码不验证:" + ConstatFinalUtil.INFO_JSON.getString("8") + admins.getFaildCount();;
						model.addAttribute("info", info);
						return "/back/login" ; 
					}
				}
				
				/*
				 * 邮箱正确，开始检验密码
				 * 注意这里的密码校验只是针对密码输错的情况，验证码输错是不会让failcount和failTime发生修改的
				 */
				if(this.encryptUtil.checkStr(password, admins.getPassword()))
				{
//					密码正确，检验状态是否可用
					if(admins.getStatus() == AAdminsEnum.STATUS_ENABLE.getStatus())
					{
						
//						为了展示用户上次的登录时间和是谁登陆的，需要将数据信息放到session中
						session.setAttribute("admins",admins);
						ConstatFinalUtil.SYS_LOGGER.info("上次登录时间{}",admins.getLastLoginTime());
						session.setAttribute("lastLoginTime", admins.getLastLoginTime());
						/*
						 * 设置完上次登录的时间之后一定要记得更新，否则数据库里的值是不会改变的
						 * 显示上次登录时间，需要先显示上次登录的时间，然后再设置上次登录的时间为当前时间
						 */
						admins.setLastLoginTime(new Date());
						this.usersService.updateOneAdminsService(admins);
						return "/back/admins/main";
						
					}else{
						info=ConstatFinalUtil.INFO_JSON.getString("3");
					}
				}else{
					/*密码不正确
					 * faildCount逐渐+1*/
					info=ConstatFinalUtil.INFO_JSON.getString("4");
					/*在这里还需要考虑两个问题
					如果第一次登陆失败，为了记录十分钟内登陆几次，需要设置一下上次登录失败的时间
					第二次登录失败的时候将不更新登陆失败的时间*/
					if(admins.getFaildCount() == 0)
					{
						admins.setFaildTime(new Date());
					}
					if(admins.getFaildCount()<Integer.valueOf((ConstatFinalUtil.CONFIG_JSON.get("password.error.lockTime")+""))
							&& new Date().getTime()- admins.getFaildTime().getTime()<Long.valueOf(ConstatFinalUtil.CONFIG_JSON.get("password.error.maxCount")+""))
					{
						info+=":"+admins.getFaildCount();
						/* 
						 * 密码的失败次数小于最大的次数
						 * 密码的时间必须在十分钟时以内
						 * 每登陆失败一次,faildCount+1,
						 * 如果登录失败就不更新上次登录的时间 */
						admins.setFaildCount(admins.getFaildCount()+1);
						this.usersService.updateOneAdminsService(admins);
					}else{
						/*锁定一段时间的提示
						 * 密码输错次数太多,请10分钟以后再试,输错次数:*/
						info="密码验证"+ConstatFinalUtil.INFO_JSON.get("6")+admins.getFaildCount();
					}
					/*如果时间超过了十分钟
					 * 第一：设置登陆时间为当前时间(这个条件不需要在此设置了，因为前面设置了当faildCount为0时
					 * 应该在登录的时候会设置当前的时间为上次登录失败的时间)
					 * 第二：设置登录失败的猜数为0*/
					if(new Date().getTime()-admins.getFaildTime().getTime()>Long.valueOf(ConstatFinalUtil.CONFIG_JSON.get("password.error.lockTime")+""))
					{
						admins.setFaildCount(0);
						this.usersService.updateOneAdminsService(admins);
					}
					return "back/login";
				}
			} else
			{
				// 邮箱不正确
				info=ConstatFinalUtil.INFO_JSON.getString("4");
			}
		}else{
//			"5":"验证码输入错误",
			info=ConstatFinalUtil.INFO_JSON.getString("5");
		}
		model.addAttribute("info",info);
		return "back/login";
	}

}
